#include "iot/thing.h"
#include "board.h"
#include "audio_codec.h"

#include <esp_log.h>
#include "driver/ledc.h"//新添加pwm控制库
#define TAG "Servo"

#define SERVO_GPIO   GPIO_NUM_14   // 连接舵机的 GPIO 引脚
// 控制参数
#define SERVO_MIN_PULSEWIDTH_US (500)   // 0度，500us
#define SERVO_MAX_PULSEWIDTH_US (2500)  // 180度，2500us
#define SERVO_MAX_DEGREE        (180)

#define SERVO_PWM_FREQ_HZ       (50)                 // SG90频率 = 50Hz
#define SERVO_PWM_TIMER         LEDC_TIMER_0
#define SERVO_PWM_MODE 			LEDC_LOW_SPEED_MODE
#define SERVO_PWM_CHANNEL       LEDC_CHANNEL_0
#define SERVO_PWM_RESOLUTION    LEDC_TIMER_13_BIT    // 2^13 = 8192

namespace iot {

// 这里仅定义 Servo 的属性和方法，不包含具体的实现
class Servo : public Thing {
private:
	uint8_t angle_ = 90;
	
	esp_err_t servo_init(gpio_num_t gpio)
	{
	    ledc_timer_config_t ledc_timer;
	    ledc_timer.speed_mode = SERVO_PWM_MODE;
	    ledc_timer.timer_num = SERVO_PWM_TIMER;
	    ledc_timer.duty_resolution = SERVO_PWM_RESOLUTION;
	    ledc_timer.freq_hz = SERVO_PWM_FREQ_HZ;
	    ledc_timer.clk_cfg = LEDC_AUTO_CLK;
	    
	    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
	
	    ledc_channel_config_t ledc_channel;
	    ledc_channel.gpio_num = gpio;
	    ledc_channel.speed_mode = SERVO_PWM_MODE;
	    ledc_channel.channel = SERVO_PWM_CHANNEL;
	    ledc_channel.intr_type = LEDC_INTR_DISABLE;
	    ledc_channel.timer_sel = SERVO_PWM_TIMER;
	    ledc_channel.duty = 0;
	    ledc_channel.hpoint = 0;
	    
	    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
	
	    return ESP_OK;
	}
	static uint32_t pwm_to_duty(uint16_t us_pulsewidth) {
		uint32_t duty = (uint32_t)((((uint64_t)us_pulsewidth * (1 << 13)) * SERVO_PWM_FREQ_HZ) / 1000000ULL);
		return duty;
	}
	esp_err_t SetAngle(uint8_t angle) {
	    if (angle > SERVO_MAX_DEGREE) {
	        angle = SERVO_MAX_DEGREE;
	    }
	
	    uint16_t pulse_width = SERVO_MIN_PULSEWIDTH_US + 
	        (SERVO_MAX_PULSEWIDTH_US - SERVO_MIN_PULSEWIDTH_US) * angle / SERVO_MAX_DEGREE;
	
	    uint32_t duty = pwm_to_duty(pulse_width);
	
	    esp_err_t err = ledc_set_duty(SERVO_PWM_MODE, SERVO_PWM_CHANNEL, duty);
	    if (err != ESP_OK) return err;
	
	    err = ledc_update_duty(SERVO_PWM_MODE, SERVO_PWM_CHANNEL);
	    if (err == ESP_OK) {
	        ESP_LOGI(TAG, "Angle: %d°, Pulse: %dus, Duty: %ld", angle, pulse_width, duty);
	    }
	    return err;
	}
public:
    Servo() : Thing("Servo", "舵机") {
		servo_init(SERVO_GPIO);
        // 定义设备的属性
        properties_.AddNumberProperty("Angle", "当前角度值", [this]() -> int {
            return angle_;
        });

        // 定义设备可以被远程执行的指令
        methods_.AddMethod("SetAngle", "设置舵机角度", ParameterList({
            Parameter("angle", "0到180之间的整数", kValueTypeNumber, true)
        }), [this](const ParameterList& parameters) {
			// angle_ = static_cast<uint8_t>(parameters["angle"].number());
			SetAngle(static_cast<uint8_t>(parameters["angle"].number()));
        });
    }
};

} // namespace iot

DECLARE_THING(Servo);